﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using System.IO;

namespace Homework_5_OrderManagementSystem
{
    class Program
    {
        static void Main(string[] args)
        {
            OrderService orderService = new OrderService();

            while (true)
            {
                Console.WriteLine("请选择操作：");
                Console.WriteLine("1. 添加订单");
                Console.WriteLine("2. 删除订单");
                Console.WriteLine("3. 修改订单");
                Console.WriteLine("4. 查询订单");
                Console.WriteLine("5. 显示所有订单");
                Console.WriteLine("6. 载入XML文件“s.xml”中的订单");
                Console.WriteLine("7. 将所有订单序列化为XML文件,并显示XML文件内容");
                Console.WriteLine("8. 退出程序");

                int choice = Convert.ToInt32(Console.ReadLine());

                switch (choice)
                {
                    case 1:
                        orderService.AddOrder();
                        break;
                    case 2:
                        orderService.RemoveOrder();
                        break;
                    case 3:
                        orderService.ModifyOrder();
                        break;
                    case 4:
                        orderService.QueryOrder();
                        break;
                    case 5:
                        orderService.DisplayAllOrders();
                        break;
                    case 6:
                        orderService.Import("s.xml");
                        break;
                    case 7:
                        orderService.Export("s.xml");
                        Console.WriteLine("\nSerialized as XML:");
                        Console.WriteLine(File.ReadAllText("s.xml"));
                        break;
                    case 8:
                        Environment.Exit(0);
                        break;
                    default:
                        Console.WriteLine("输入错误，请重新输入！");
                        break;
                }
            }
        }
    }

    public class Order
    {
        public int OrderId { get; set; }
        public string CustomerName { get; set; }
        public double TotalPrice { get; set; }
        public List<OrderDetail> OrderDetails { get; set; }
        public double GetTotalPrice()
        {
            TotalPrice = OrderDetails.Sum(detail => detail.Quantity * detail.UnitPrice);
            return TotalPrice;
        }
        public override string ToString()
        {
            return $"订单号：{OrderId}，客户名：{CustomerName}，订单总金额：{TotalPrice}";
        }

        public override bool Equals(object obj)
        {
            return obj is Order order &&
                   OrderId == order.OrderId;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode() + OrderId * 13579 + (int)TotalPrice * 13579;
        }
    }

    public class OrderDetail
    {
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public double UnitPrice { get; set; }

        public override string ToString()
        {
            return $"商品名：{ProductName}，商品数量：{Quantity}，商品单价：{UnitPrice}";
        }

        public override bool Equals(object obj)
        {
            return obj is OrderDetail detail &&
                   ProductName == detail.ProductName;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode() + Quantity * 13579 + (int)UnitPrice * 13579;
        }
    }

    public class OrderService
    {
        List<Order> orders;
        public List<Order> GetOrders()//测试用
        {
            return orders;
        }
        public int GetAllOrders()
        {
            return orders.Count();
        }
        public OrderService()
        {
            orders = new List<Order>();
        }


        public void Export(string fileName)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate))
            {
                xmlSerializer.Serialize(fileStream, orders);
            }
            Console.WriteLine($"所有订单已经成功序列化为XML文件{fileName}！");
        }

        public void Import(string fileName)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fileStream = new FileStream(fileName, FileMode.Open))
            {
                List<Order> importedOrders = (List<Order>)xmlSerializer.Deserialize(fileStream);
                foreach (Order order in importedOrders)
                {
                    if (orders.Any(o => o.Equals(order)))
                    {
                        throw new Exception($"订单号为{order.OrderId}的订单已经存在！");
                    }
                    orders.Add(order);
                }
            }
            Console.WriteLine($"XML文件{fileName}已经成功载入！");
        }

        public void DisplayAllOrders()
        {
            if (orders.Count == 0)
            {
                Console.WriteLine("没有任何订单");
            }
            else
            {
                foreach (Order order in orders)
                {
                    Console.WriteLine(order);
                }
            }
        }

        public void AddOrder()
        {
            Console.WriteLine("请输入订单信息：");
            Console.Write("订单号：");
            int orderId = Convert.ToInt32(Console.ReadLine());

            if (orders.Any(o => o.OrderId == orderId))
            {
                throw new Exception($"订单号为{orderId}的订单已经存在！");
            }

            Console.Write("客户名：");
            string customerName = Console.ReadLine();

            Console.Write("请输入订单明细信息（格式：商品名,商品数量,商品单价;商品名,商品数量,商品单价）：");
            string input = Console.ReadLine();
            string[] detailInfos = input.Split(';');

            List<OrderDetail> orderDetails = new List<OrderDetail>();
            foreach (string detailInfo in detailInfos)
            {
                string[] info = detailInfo.Split(',');
                string productName = info[0];
                int quantity = Convert.ToInt32(info[1]);
                double unitPrice = Convert.ToDouble(info[2]);
                OrderDetail orderDetail = new OrderDetail()
                {
                    ProductName = productName,
                    Quantity = quantity,
                    UnitPrice = unitPrice
                };

                if (orderDetails.Contains(orderDetail))
                {
                    throw new Exception($"商品名为{productName}的商品已经存在！");
                }

                orderDetails.Add(orderDetail);
            }

            Order order = new Order()
            {
                OrderId = orderId,
                CustomerName = customerName,
                OrderDetails = orderDetails,
                TotalPrice = orderDetails.Sum(detail => detail.Quantity * detail.UnitPrice)
            };

            orders.Add(order);

            Console.WriteLine($"订单{orderId}添加成功！");
        }
        public void AddOrder(Order order)//测试时使用，添加一个已有订单
        {
            orders.Add(order);
        }

        public void RemoveOrder()
        {
            Console.WriteLine("请输入要删除的订单号：");
            int orderId = Convert.ToInt32(Console.ReadLine());

            Order orderToRemove = orders.FirstOrDefault(order => order.OrderId == orderId);
            if (orderToRemove != null)
            {
                orders.Remove(orderToRemove);
                Console.WriteLine($"订单{orderId}删除成功！");
            }
            else
            {
                throw new Exception($"订单号为{orderId}的订单不存在！");
            }
        }
        public void RemoveOrder(int index)//重载，该方法用于测试
        {
            int orderId = index;
            Order orderToRemove = orders.FirstOrDefault(order => order.OrderId == orderId);
            if (orderToRemove != null)
            {
                orders.Remove(orderToRemove);
                Console.WriteLine($"订单{orderId}删除成功！");
            }
            else
            {
                throw new Exception($"订单号为{orderId}的订单不存在！");
            }
        }

        public void ModifyOrder()
        {
            Console.WriteLine("请输入要修改的订单号：");
            int orderId = Convert.ToInt32(Console.ReadLine());

            Order orderToModify = orders.FirstOrDefault(order => order.OrderId == orderId);
            if (orderToModify != null)
            {
                Console.WriteLine($"当前订单信息为：{orderToModify}");

                Console.WriteLine("请输入新的客户名（不修改请按回车）：");
                string customerName = Console.ReadLine();
                if (!string.IsNullOrEmpty(customerName))
                {
                    orderToModify.CustomerName = customerName;
                }

                Console.WriteLine("请输入新的订单明细信息（格式：商品名,商品数量,商品单价;商品名,商品数量,商品单价；不修改请按回车）：");
                string input = Console.ReadLine();
                if (!string.IsNullOrEmpty(input))
                {
                    orderToModify.OrderDetails.Clear();
                    string[] detailInfos = input.Split(';');

                    List<OrderDetail> orderDetails = new List<OrderDetail>();
                    foreach (string detailInfo in detailInfos)
                    {
                        string[] info = detailInfo.Split(',');
                        string productName = info[0];
                        int quantity = Convert.ToInt32(info[1]);
                        double unitPrice = Convert.ToDouble(info[2]);

                        OrderDetail orderDetail = new OrderDetail()
                        {
                            ProductName = productName,
                            Quantity = quantity,
                            UnitPrice = unitPrice
                        };

                        if (orderDetails.Contains(orderDetail))
                        {
                            throw new Exception($"商品名为{productName}的商品已经存在！");
                        }

                        orderDetails.Add(orderDetail);
                    }

                    orderToModify.OrderDetails = orderDetails;
                    orderToModify.TotalPrice = orderDetails.Sum(detail => detail.Quantity * detail.UnitPrice);
                }

                Console.WriteLine($"订单{orderId}修改成功！");
            }
            else
            {
                throw new Exception($"订单号为{orderId}的订单不存在！");
            }
        }

        public void ModifyOrder(Order neworder)//重载，该方法用于测试
        {
            int orderId = neworder.OrderId;
            string customerName = neworder.CustomerName;
            Order orderToModify = orders.FirstOrDefault(order => order.OrderId == orderId);
            orderToModify.OrderId = orderId;
            orderToModify.CustomerName = customerName;
            orderToModify.OrderDetails = neworder.OrderDetails;
            orderToModify.TotalPrice = neworder.OrderDetails.Sum(detail => detail.Quantity * detail.UnitPrice);
        }

        public void QueryOrder()
        {
            Console.WriteLine("请选择查询方式：");
            Console.WriteLine("1. 按订单号查询");
            Console.WriteLine("2. 按商品名称查询");
            Console.WriteLine("3. 按客户查询");
            Console.WriteLine("4. 按订单金额查询");

            int choice = Convert.ToInt32(Console.ReadLine());

            switch (choice)
            {
                case 1:
                    Console.WriteLine("请输入订单号：");
                    int orderId = Convert.ToInt32(Console.ReadLine());

                    var queryById = from order in orders
                                    where order.OrderId == orderId
                                    orderby order.TotalPrice
                                    select order;
                    foreach (var order in queryById)
                    {
                        Console.WriteLine(order);
                    }
                    break;
                case 2:
                    Console.WriteLine("请输入商品名称：");
                    string productName = Console.ReadLine();
                    var queryByProductName = from order in orders
                                             where order.OrderDetails.Any(detail => detail.ProductName == productName)
                                             orderby order.TotalPrice
                                             select order;
                    foreach (var order in queryByProductName)
                    {
                        Console.WriteLine(order);
                    }
                    break;
                case 3:
                    Console.WriteLine("请输入客户名：");
                    string customerName = Console.ReadLine();

                    var queryByCustomerName = from order in orders
                                              where order.CustomerName == customerName
                                              orderby order.TotalPrice
                                              select order;
                    foreach (var order in queryByCustomerName)
                    {
                        Console.WriteLine(order);
                    }
                    break;
                case 4:
                    Console.WriteLine("请输入订单金额范围（格式：最小金额,最大金额）：");
                    string[] priceRange = Console.ReadLine().Split(',');
                    double minPrice = Convert.ToDouble(priceRange[0]);
                    double maxPrice = Convert.ToDouble(priceRange[1]);

                    var queryByPrice = from order in orders
                                       where order.TotalPrice >= minPrice && order.TotalPrice <= maxPrice
                                       orderby order.TotalPrice
                                       select order;
                    foreach (var order in queryByPrice)
                    {
                        Console.WriteLine(order);
                    }
                    break;
                default:
                    Console.WriteLine("无效的选择！");
                    break;
            }
        }
        public Order QueryOrdersByCustomerName(string customerName)//测试用
        {
            var queryByCustomerName = from order in orders
                                      where order.CustomerName == customerName
                                      orderby order.TotalPrice
                                      select order;
            foreach (var order in queryByCustomerName)
            {
                return order;
            }
            return null;
        }
        public Order QueryOrdersByID(int orderId)//测试用
        {
            var queryById = from order in orders
                            where order.OrderId == orderId
                            orderby order.TotalPrice
                            select order;
            foreach (var order in queryById)
            {
                return order;
            }
            return null;
        }

        public void SortOrders()
        {
            Console.WriteLine("请选择排序方式：");
            Console.WriteLine("1. 按订单号排序");
            Console.WriteLine("2. 按订单总金额排序");

            int choice = Convert.ToInt32(Console.ReadLine());

            switch (choice)
            {
                case 1:
                    orders.Sort();
                    Console.WriteLine("按订单号排序成功！");
                    break;
                case 2:
                    orders.Sort((order1, order2) => order1.TotalPrice.CompareTo(order2.TotalPrice));
                    Console.WriteLine("按订单总金额排序成功！");
                    break;
                default:
                    Console.WriteLine("无效的选择！");
                    break;
            }
        }
        public void SortOrdersById()//测试用
        {// 按订单号升序排序
            orders.Sort((o1, o2) => o1.OrderId - o2.OrderId);
        }
        public void SortOrdersByTotallPrice()//测试用
        { // 按订单总金额降序排序
            orders.Sort((o1, o2) => (int)(o2.TotalPrice - o1.TotalPrice));
        }
    }
}
